Android 系統自問世以來,就以「應用隔離」與「權限管控」為核心安全設計。每個應用都執行在自己獨立的 UID 與 sandbox 中,想要存取敏感資源(如相機、定位、通訊錄)都必須透過權限系統授權。
而在整個權限體系中,PermissionManagerService(PMSv2) 是 framework 層的關鍵角色,負責:
在深入 PermissionManagerService 之前,先看整體權限架構:
+-----------------------------------------------------------+
| Application 層 |
| (App 請求權限、顯示 runtime dialog、存取受保護 API) |
+-----------------------------------------------------------+
| Framework Service 層 |
| PermissionManagerService、AppOpsService、AMS、PMS |
+-----------------------------------------------------------+
| Native 層 (JNI) |
| libbinder, libcutils, SELinux policy, system_server |
+-----------------------------------------------------------+
| Kernel 層 |
| UID/GID, SELinux, capabilities |
+-----------------------------------------------------------+
權限管理的四大核心概念:
<uses-permission> 宣告所需權限。在 SystemServer.java 啟動階段:
t.traceBegin("StartPermissionManagerService");
mSystemServiceManager.startService(PermissionManagerService.class);
t.traceEnd();
這使得 PermissionManagerService 成為系統服務之一,透過 Binder 暴露給其他 framework 元件。
public final class PermissionManagerService extends SystemService {
private final PermissionRegistry mRegistry;
private final DefaultPermissionGrantPolicy mDefaultGrantPolicy;
private final PermissionSettings mSettings;
}
當應用呼叫:
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), REQ_CODE)
系統會經過以下流程:
[App層] requestPermissions()
↓
[AMS] -> startActivityForResult() 啟動 PermissionDialog Activity
↓
[PermissionController Service] 顯示授權對話框
↓
[PermissionManagerService] 接收結果、更新授權記錄
↓
[PackageManagerService] 更新 packages.xml
若使用者點選「允許」,PermissionManagerService 將:
當 App 呼叫需要權限的 API,例如:
val location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
Framework 流程如下:
App 呼叫 → LocationManagerService
↓
LocationManagerService.checkPermission()
↓
PermissionManagerService.checkUidPermission(uid, permission)
↓
AppOpsService.noteOp() → 檢查是否被暫時封鎖
↓
若通過 → 執行 API
否則 → 拋出 SecurityException
PMS 實際檢查的核心程式碼:
int checkUidPermission(String permName, int uid) {
synchronized (mLock) {
Permission permission = mRegistry.getPermission(permName);
return permission.isGranted(uid) ? PERMISSION_GRANTED : PERMISSION_DENIED;
}
}
Android 權限主要分為四種保護等級:
| 類型 | 範例 | 授權機制 | 使用者互動 |
|---|---|---|---|
| normal | INTERNET | 自動授權 | 無 |
| dangerous | CAMERA、LOCATION | 需 runtime 授權 | 有 |
| signature | READ_LOGS、MANAGE_USERS | 必須同簽章 | 無 |
| signatureOrSystem | (舊版已棄用) | 由系統預設授權 | 無 |
此外,自 Android 12 起,又引入了 permission group 與 one-time permission 概念,使授權更精細化與動態化。
PermissionManagerService 不獨立運作,它與其他三個關鍵服務緊密合作:
| 服務名稱 | 職責 | 與 PMS 的互動 |
|---|---|---|
| PackageManagerService (PMS) | 管理 App 安裝與 metadata | 安裝 App 時載入 uses-permission |
| ActivityManagerService (AMS) | 控制應用執行 | 啟動授權 dialog、更新運行狀態 |
| AppOpsService | 控制 App 實際存取操作 | 補充權限層不足的情境控制 |
| PermissionController Service | 提供 UI 層授權界面 | 與 PMS 溝通 runtime 結果 |
+-------------------------+
| PermissionController |
| (Dialog UI, UX Flow) |
+-----------+-------------+
|
v
+-------------------------+
| PermissionManagerService|
+-----------+--------------+
|
+-----------+--------------+
| AppOpsService |
| ActivityManagerService |
| PackageManagerService |
+-----------+--------------+
|
v
+-------------------------+
| System Server / Binder|
+-------------------------+
PermissionManagerService 並非唯一的安全守門員。
在 kernel 層,還有 UID sandboxing 與 SELinux policy 兩層防護:
授權資訊儲存在:/data/system/packages.xml
Ex.
<package name="com.example.camera" codePath="/data/app/com.example.camera">
<perms>
<item name="android.permission.CAMERA" granted="true" />
</perms>
</package>
當系統重新啟動時,PermissionManagerService 會重新載入這些紀錄,確保授權狀態一致。
在使用前動態檢查:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), 0)
}
正確處理 callback:
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// granted
}
}
避免過度要求敏感權限,特別是在 Google Play 發布政策中,需有明確用途說明。
PermissionManagerService 是 Android 權限體系的核心組件之一,它串連了從 App 層的授權請求、系統層的狀態記錄 到 安全層的防護策略。
透過與 PMS、AMS、AppOpsService 的協同合作,它確保了: